/**
   @file sys_usw_xdata.h

   @date 2022-06-16

   @version v1.0

   The file contains all xdata inner APIs of sys layer

 */
 #if defined(ARCTIC)
 #ifndef _SYS_USW_XDATA_NEW_H
#define _SYS_USW_XDATA_NEW_H

#ifdef __cplusplus
extern "C" {
#endif
/****************************************************************************
*
* Header Files
*
****************************************************************************/
#include "sal.h"
#include "ctc_xdata.h"
#include "ctc_field.h"
#include "sys_usw_xdata_api.h"

/****************************************************************************
 *
 * Defines and Macros
 *
 *****************************************************************************/

#define SYS_XDATA_ENCODE_PROF_VECTOR_IDX(type, prof_id) ((type)<<3 | (prof_id))
#define SYS_XDATA_ENCODE_PATH_VECTOR_IDX(type, prof_id) ((type)<<3 | (prof_id))
#define SYS_XDATA_ENCODE_LOCAL_MAP(_field, _bmp, _is_done) \
{\
    map[num].field = (_field);\
    map[num].bmp = (_bmp);\
    map[num].is_done = (_is_done);\
    num++;\
}

#define SYS_XDATA_LOCK(lchip) \
    if(p_xdata_master[lchip]->mutex) sal_mutex_lock(p_xdata_master[lchip]->mutex)

#define SYS_XDATA_UNLOCK(lchip) \
    if(p_xdata_master[lchip]->mutex) sal_mutex_unlock(p_xdata_master[lchip]->mutex)

#define CTC_USW_RETURN_XDATA_UNLOCK(op) \
    do \
    { \
        sal_mutex_unlock(p_xdata_master[lchip]->mutex); \
        return (op); \
    } while (0)

#define CTC_USW_ERROR_RETURN_XDATA_UNLOCK(op) \
    do \
    { \
        int32 rv = (op); \
        if (rv < 0) \
        { \
            sal_mutex_unlock(p_xdata_master[lchip]->mutex); \
            return rv; \
        } \
    } while (0)

#define SYS_XDATA_INIT_CHECK()         \
    {                                \
        LCHIP_CHECK(lchip);          \
        if (!p_xdata_master[lchip]) {           \
            return CTC_E_NOT_INIT; } \
    }

#define SYS_XDATA_DBG_OUT(level, FMT, ...)    CTC_DEBUG_OUT(xdata, xdata, XDATA_SYS, level, FMT, ## __VA_ARGS__)

#define SYS_XDATA_MAX_VALUE_CHECK(var, max_value, ret_value)     if ((var) > (max_value)){return (ret_value); }


#define SYS_XDATA_PROF_FIELD_MAX         16
#define SYS_XDATA_LOCAL_FIELD_MAX        14
#define SYS_XDATA_PATH_FIELD_MAX         16

#define SYS_XDATA_WIDTH_NIBBLE        0
#define SYS_XDATA_WIDTH_BYTE          1
#define SYS_XDATA_WIDTH_WORD          2
#define SYS_XDATA_WIDTH_DWORD         3
#define SYS_XDATA_WIDTH_QWORD         4
#define SYS_XDATA_WIDTH_NUM           5


/****************************************************************
*
*xdata
*
****************************************************************/
struct sys_xdata_prof_field_s
{
    uint32 width       : 5;
    uint32 src_offset  : 8;
    uint32 dst_offset  : 8;
    uint32 rsv         : 11;
};
typedef struct sys_xdata_prof_field_s sys_xdata_prof_field_t;

struct sys_xdata_prof_info_s
{
    uint32  num              :5;
    uint32  rsv              :27;
    sys_xdata_prof_field_t field[SYS_XDATA_PROF_FIELD_MAX];
};
typedef struct sys_xdata_prof_info_s sys_xdata_prof_info_t;


/****************************************************************
*
*xdata path
*
****************************************************************/

struct sys_xdata_path_field_s
{
    uint32 width       : 5;
    uint32 src_offset  : 8;
    uint32 dst_offset  : 8;
    uint32 rsv         : 11;
};
typedef struct sys_xdata_path_field_s sys_xdata_path_field_t;

struct sys_xdata_path_info_s
{
    uint32 fixed_bmp         :16;
    uint32 num               :5;
    uint32  rsv              :11;

    uint32  valid_bmp;/* dst-offset bmp in 4bits,for check*/

    sys_xdata_path_field_t field[SYS_XDATA_PATH_FIELD_MAX];
};
typedef struct sys_xdata_path_info_s sys_xdata_path_info_t;

/****************************************************************
*
*local xdata
*
****************************************************************/

struct sys_xdata_local_field_s
{
    uint32 width       : 5;
    uint32 src_offset  : 8;
    uint32 dst_offset  : 8;
    uint32 rvs         :11;
};
typedef struct sys_xdata_local_field_s sys_xdata_local_field_t;

struct sys_xdata_local_s
{
    uint32 type       :4;
    uint32 mode       :2; /* 0,only xdata; 1,only ctc_field, 2, mix local xdata */
    uint32 num        :4;
    uint32 ref_cnt    :6;
    uint32 rsv        :16;
    sys_xdata_local_field_t  field[SYS_XDATA_LOCAL_FIELD_MAX];
};
typedef struct sys_xdata_local_s sys_xdata_local_t;

struct sys_xdata_local_fixed_map_s
{
    uint32 field       :10;
    uint32 bmp         :14;
    uint32 is_done     :1;  /* indate last field */
    uint32 rsv         :7;
};
typedef struct sys_xdata_local_fixed_map_s sys_xdata_local_fixed_map_t;

struct sys_xdata_local_mapping_s
{
    uint32 width    :5;
    uint32 offset   :8; 
    uint32 rsv      :19;
};
typedef struct sys_xdata_local_mapping_s sys_xdata_local_mapping_t;

/****************************************************************
*
*flex key
*
****************************************************************/

#define SYS_FK_F_STD_FIELD_NUM      (SYS_FK_F_XDATA_WORD3-SYS_FK_F_XDATA_NIBBLE0+1)

struct sys_xdata_fk_f_db_s
{
    /*input*/
    uint32 field          :8;/*  refer to sys_xdata_fk_f_type_t*/
    uint32 father_field   :8;/* share field*/
    uint32 drv_offset     :10; /* write table field start bit offset */
    uint32 width          :6;  /* 4/8/16 container width */

    /*store*/
    char *ptr_field_name;

    uint32 pos_sel        :6;  /* in 4 bits */
    uint32 start_bit      :4;  /* field real start bit in container */
    uint32 bit_width      :5;  /* field reld bit width in container */
    uint32 mask           :17;/* xdata mask in container*/

};
typedef struct sys_xdata_fk_f_db_s sys_xdata_fk_f_db_t;

#define SYS_FK_MASK_LEN   80

/* buffer */
struct sys_xdata_std_field_s
{
    uint16 bitmap;
    uint8  width;
    uint8  cur_index;
    sys_xdata_fk_f_db_t* pf_db_node[SYS_FK_F_STD_FIELD_NUM];
    XKeyGenProfile_m profile;
    uint32 mask[SYS_FK_MASK_LEN/sizeof(uint32)];
};
typedef struct sys_xdata_std_field_s sys_xdata_std_field_t;

struct sys_xdata_fk_db_s
{
   /*hash key*/
    uint32 type            :8;   /*refer to sys_xdata_local_type_t*/
    uint32 hash_type       :8;
    uint32 rsv0            :16;
    uint32 tbl_id;      /*hash/tcam or Normal tabel*/

    ctc_linklist_t* field_list; 
    uint32 mode            :2;/*refer to SYS_FK_MODE_XXX*/
    uint32 fk_prof_id      :4;
    uint32 fk_mask_id      :4;
    uint32 key_sel         :4;/*keygen key select for xkset: 1-nibbleKey,2-byteKey...*/
    uint32 type_sel        :8;    /*type sel for xlookup or xhash */
    uint32 udf_bmp         :8;
    uint32 key_size        :2;


    uint32 is_install      :2;
    uint32 udf_en          :1;
    uint32 is_direct_key   :1;
    uint32 rsv1            :28;

    sys_xdata_std_field_t* p_std_field; /* buffer */
};
typedef struct sys_xdata_fk_db_s sys_xdata_fk_db_t;


/****************************************************************
*
*master
*
****************************************************************/

struct sys_xdata_fk_f_info_s {
    uint32 src_pos           :5;
    uint32 width             :5;
    uint32 bit_width         :5;
    uint32 offset            :5;
    uint32 share_field       :8;
    uint32 rsv               :4;
};
typedef struct  sys_xdata_fk_f_info_s sys_xdata_fk_f_info_t;

typedef struct sys_xdata_kset_s {
    uint32 w[CTC_B2W_SIZE(CTC_FIELD_KEY_NUM)];
} sys_xdata_kset_t;


struct sys_xdata_master_s
{
    ctc_vector_t* prof_vec;
    ctc_vector_t* path_vec;

    ctc_hash_t* fk_hash;
    uint8 path_bmp[CTC_XDATA_PATH_TYPE_MAX];
    uint8 prof_bmp[SYS_XDATA_PROF_TYPE_MAX];
    sys_xdata_local_fixed_map_t* fixed_map[SYS_XDATA_LOCAL_TYPE_MAX];
    sys_xdata_local_t local[SYS_XDATA_LOCAL_TYPE_MAX];
    sys_xdata_fk_f_info_t fk_f_info[SYS_XDATA_LOCAL_TYPE_MAX][SYS_FK_F_MAX];
    sys_xdata_kset_t kset[SYS_XDATA_LOCAL_TYPE_MAX];
    sal_mutex_t * mutex;
    uint8 opf_type_fk_prof;
    uint8 opf_type_fk_mask;
    uint8 logic_port_ext_bmp; /* for bsr->epe CTC_XDATA_FIXED_FIELD_LOGIC_PORT_EXT */
};
typedef struct sys_xdata_master_s  sys_xdata_master_t;

extern sys_xdata_master_t* p_xdata_master[CTC_MAX_LOCAL_CHIP_NUM_PP];

typedef struct
{
    uint32 tbl_id;
    uint32 fld_id:24;
    uint32 append:8;
}_sys_xdata_fk_info_t;

extern int32
_sys_usw_xdata_set_profile(uint8 lchip, ctc_xdata_prof_t * p_prof);

extern int32
_sys_usw_xdata_get_profile(uint8 lchip, ctc_xdata_prof_t * p_prof);

extern int32
_sys_usw_xdata_set_path(uint8 lchip, ctc_xdata_path_t * p_path);

extern int32
_sys_usw_xdata_get_path(uint8 lchip, ctc_xdata_path_t * p_path);

extern int32
_sys_usw_xdata_set_local(uint8 lchip, ctc_xdata_local_t * p_local);

extern int32
_sys_usw_xdata_get_local(uint8 lchip, ctc_xdata_local_t * p_local);

extern const _sys_xdata_fk_info_t*
sys_usw_xdata_get_fk_info(uint8 lchip, sys_xdata_fk_db_t * p_fk_node);

extern int32
_sys_usw_xdata_func_en(uint8 lchip, sys_xdata_func_t type, uint8 enable, void* data);

extern int32
_sys_usw_xdata_show_solid_map(uint8 lchip, uint8 type, uint8 sub_type);

#ifdef __cplusplus
}
#endif
#endif
#endif


